package com.simen.hellobytes.encrypt;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * Hmac==OSX
 * Java7提供了对HmacMD5(128)\HmacSHA1(160)\HmacSHA256(256)\HmacSHA384(384)\HmacSHA512(512)支持
 *
 * @author Created by Simen.
 * @date 创建日期 2018/9/27 23:04
 * @modify 修改者 Simen
 */
public class HmacUtil {

    public static final String HMAC_MD5 = "HmacMD5";
    public static final String HMAC_SHA1 = "HmacSHA1";
    public static final String HMAC_SHA256 = "HmacSHA256";
    public static final String HMAC_SHA384 = "HmacSHA384";
    public static final String HMAC_SHA512 = "HmacSHA512";

    public static byte[] initHmacMD5Key() throws NoSuchAlgorithmException {
        return initHmacKey(HMAC_MD5);
    }

    public static byte[] initHmacSHA1Key() throws NoSuchAlgorithmException {
        return initHmacKey(HMAC_SHA1);
    }

    /**
     * 初始化Hmac密钥
     *
     * @param algorithm
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static byte[] initHmacKey(String algorithm) throws NoSuchAlgorithmException {
        //初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
        //产生密钥
        SecretKey secretKey = keyGenerator.generateKey();
        //获得密钥
        return secretKey.getEncoded();
    }

    public static byte[] encodeHmacMD5(byte[] key, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException {
        return encodeHmac(HMAC_MD5, key, data);
    }

    public static byte[] encodeHmacSHA1(byte[] key, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException {
        return encodeHmac(HMAC_SHA1, key, data);
    }

    /**
     * Hmac消息摘要实现
     *
     * @param algorithm
     * @param key
     * @param data
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static byte[] encodeHmac(String algorithm, byte[] key, byte[] data) throws NoSuchAlgorithmException, InvalidKeyException {
        //还原密钥
        SecretKey secretKey = new SecretKeySpec(key, algorithm);
        //实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        //初始化Mac
        mac.init(secretKey);
        //执行消息摘要
        return mac.doFinal(data);
    }

}
